﻿namespace dogd
{
	using System;

	/// <summary>
	/// FilterBy is used in sql generation by SqlStatementGenerator
	/// </summary>
	public class FilterBy
	{
		private const string AtVariable = "@";

		/// <summary>
		/// Initialize with column name. Assumes equality and variable name is the same as the column name.
		/// </summary>
		/// <param name="name"></param>
		public FilterBy(string name)
			: this(name, FilterOperator.Equal, AtVariable + name)
		{
		}

		/// <summary>
		/// Initialize with a column name and variable name. Assumes equality comparison.
		/// </summary>
		/// <param name="columnName"></param>
		/// <param name="variableName"></param>
		public FilterBy(string columnName, string variableName)
			: this(columnName, FilterOperator.Equal, AtVariable + variableName)
		{
		}

		/// <summary>
		/// Initialize with name, operator and value
		/// </summary>
		/// <param name="name"></param>
		/// <param name="op"></param>
		/// <param name="value"></param>
		public FilterBy(string name, FilterOperator op, string value)
		{
			if (string.IsNullOrEmpty(name))
			{
				throw new ArgumentNullException("name");
			}

			if (string.IsNullOrEmpty(value) || value == AtVariable)
			{
				throw new ArgumentNullException("value");
			}

			this.Name = name;
			this.Operator = op;

			if (value.StartsWith(AtVariable))
			{
				this.Value = value;
			}
			else
			{
				this.Value = "\'" + value + "\'";
			}
		}

		/// <summary>
		/// Initialize with name, operator and object value
		/// </summary>
		/// <param name="name"></param>
		/// <param name="op"></param>
		/// <param name="value"></param>
		public FilterBy(string name, FilterOperator op, object value)
		{
			if (string.IsNullOrEmpty(name))
			{
				throw new ArgumentNullException("name");
			}

			this.Name = name;
			this.Operator = op;
			this.Value = value.ToString();
		}

		/// <summary>
		/// Initialize from reflected metadata. Assumes equality comparison
		/// </summary>
		/// <param name="metadata"></param>
		public FilterBy(ColumnMetadata metadata)
			: this(metadata.ColumnName, FilterOperator.Equal, metadata.Parameter)
		{
		}

		/// <summary>
		/// Column Name
		/// </summary>
		public string Name
		{
			get;
			set;
		}

		/// <summary>
		/// Comparison operator
		/// </summary>
		public FilterOperator Operator
		{
			get;
			set;
		}

		/// <summary>
		/// Value to test against
		/// </summary>
		public string Value
		{
			get;
			set;
		}

		/// <summary>
		/// Override to provide sql fragment for this object.
		/// </summary>
		/// <returns></returns>
		public override string ToString()
		{
			return string.Format("{0} {1} {2}", this.Name, this.Operator.ToDescription(), this.Value);
		}
	}
}
